﻿using P2P.CrossPlatform.SystemInfo;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace P2P.CrossPlatform
{
    public class ProcessMonitor
    {
        private double _currentCpuUsage;
        private double[] _cpuUsageHistory = new double[60]; // 保存最近60个数据点的CPU使用率历史
        private int _cpuHistoryIndex = 0;

        private double _totalMemoryGB;
        private double _currentMemoryUsageMB;
        private double[] _memoryUsageHistory = new double[60]; // 保存最近60个数据点的内存使用率历史
        private int _memoryHistoryIndex = 0;

        private static volatile ProcessMonitor _instance;
        private readonly static object _lock = new object();
        
        private bool _runing = true;

        private ProcessMonitor() { }

        public static ProcessMonitor Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (_lock)
                    {
                        if (_instance == null)
                        {
                            _instance = new ProcessMonitor();
                        }
                    }
                }
                return _instance;
            }
        }

        public void StartMonitor(Action<Result> callback) 
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Task.Run(async () =>
                {
                    Win32SystemInfo sys = new Win32SystemInfo();
                    const int MB_DIV = 1024 * 1024;
                    const int GB_DIV = 1024 * 1024 * 1024;
                    while (_runing)
                    {
                        _currentCpuUsage = Math.Round(sys.CpuLoad,2);
                        _cpuUsageHistory[_cpuHistoryIndex] = _currentCpuUsage;
                        _cpuHistoryIndex = (_cpuHistoryIndex + 1) % _cpuUsageHistory.Length; // 循环数组

                        _currentMemoryUsageMB = Math.Round((sys.PhysicalMemory - sys.MemoryAvailable) / (double)MB_DIV,2);

                        _totalMemoryGB = Math.Round(sys.PhysicalMemory / (double)GB_DIV,2);

                        _memoryUsageHistory[_memoryHistoryIndex] = _currentMemoryUsageMB;
                        _memoryHistoryIndex = (_memoryHistoryIndex + 1) % _memoryUsageHistory.Length; // 循环数组

                        callback(new Result
                        {
                            TotalMemoryGB = _totalMemoryGB,
                            CpuUsageHistory = _cpuUsageHistory,
                            MemoryUsageHistory = _memoryUsageHistory,
                            CurrentCpuUsage = _currentCpuUsage,
                            CurrentMemoryUsageMB = _currentMemoryUsageMB,
                            CurrentMemoryUsageGB = Math.Round(_currentMemoryUsageMB / 1024,2)
                        });

                        await Task.Delay(1000);
                    }
                });

            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {

            }
        }

        public void Stop() 
        {
            _runing = false;
        }
    }

    public class Result 
    {
        public double CurrentCpuUsage;
        public double[] CpuUsageHistory = new double[60]; // 保存最近60个数据点的CPU使用率历史
        public double TotalMemoryGB;
        public double CurrentMemoryUsageMB;
        public double CurrentMemoryUsageGB;
        public double[] MemoryUsageHistory = new double[60]; // 保存最近60个数据点的内存使用率历史
    }
}
